﻿Imports System.IO

Public Class Form1

    Dim serialPort As IO.Ports.SerialPort
    Dim receiveBuffer() As Byte

    Dim running As Boolean = True
    Dim TimeStart As Date
    Dim TimeNow As Date
    Dim DeltaTime As TimeSpan
    Dim ChartResetTime As TimeSpan
    Dim LastReset As Date
    Dim FirstData As Boolean = False
    Dim fileName As String = Application.StartupPath & "\data\" & "GSTextData " & Now.Year.ToString & "-" & Now.Month.ToString & "-" & Now.Day.ToString & " " & Now.Hour & "." & Now.Minute & ".txt"

    Dim writeOffset As Long = 0
    Dim readOffset As Long = 0

    Dim Message() As Byte
    Dim messageReceived As Boolean = False

    Dim PressureChamberTemperatureGraph As New DataTable
    Dim VacuumChamberTemperatureGraph As New DataTable
    Dim PressureChamberPressureGraph As New DataTable
    Dim VacuumChamberPressureGraph As New DataTable
    Dim ResWire1Graph As New DataTable
    Dim ResWire2Graph As New DataTable

    Dim PressureChamberTemperatureAverage As Integer
    Dim VacuumChamberTemperatureAverage As Integer
    Dim PressureChamberPressureAverage As Integer
    Dim VacuumChamberPressureAverage As Integer
    Dim ResWire1Average As Integer
    Dim ResWire2Average As Integer
    Dim DataSampleCount As Byte

    Dim TIMEMAXFORGRAPH As Integer = 600
    Dim GRAPHUPDATETIME As Integer = 600

    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        running = False
        End
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        SetupGraphs()

        serialPort = New IO.Ports.SerialPort("COM3", 38400, IO.Ports.Parity.None, 8, IO.Ports.StopBits.One)
        serialPort.Open()
        Me.Show()
        Me.Focus()
        ReDim receiveBuffer(1023)
        If Not IO.Directory.Exists(Application.StartupPath & "\data\") Then
            IO.Directory.CreateDirectory(Application.StartupPath & "\data\")
        End If

        printText("Initialization successfull")
        printText("Listening for UART")
        printText("Saving RAW data to: " & fileName)

        While running = True
            Application.DoEvents()
            Me.Text = "Solar groundstation - " & writeOffset
            If serialPort.BytesToRead > 0 Then
                putByte(serialPort.ReadByte())
            End If
            If messageReceived = True Then
                HandleMessage()
            End If
        End While

        serialPort.Dispose()

    End Sub

    Private Sub HandleMessage()
        If Message.Length > 5 Then
            Dim checksum() As Byte = generateChecksum(Message)

            'Check that the checksum is correct, otherwise discard the message.
            If checksum(0) = Message(Message.Length - 5) And checksum(1) = Message(Message.Length - 4) Then

                'Saves the message in raw form to a textfile for backup.
                Dim tempString As String = ""
                Dim j As Integer = 0
                While j <> Message.Length
                    tempString = tempString & " " & CStr(Message(j))
                    j = j + 1
                End While
                tempString = tempString & vbNewLine
                File.AppendAllText(fileName, tempString)

                Select Case Message(0)
                    Case 1 'Experiment OK
                        If Message.Length = 10 Then
                            ExperimentOKTextBox.BackColor = Color.Green
                        Else
                            printText("Message length error: MESSAGE_OK")
                        End If
                    Case 2 'Error
                        printText("Error occured")  'None in AVR
                    Case 4 'DATA
                        If Message.Length = 22 Then
                            If FirstData = False Then
                                TimeStart = Now
                                LastReset = Now
                                FirstData = True
                            End If
                            DataSampleCount = DataSampleCount + 1
                            ReadDataMessage()
                            If DataSampleCount = 10 Then
                                TimeNow = Now
                                DeltaTime = (TimeNow - TimeStart)
                                PressureChamberTemperatureGraph.Rows.Add(DeltaTime.TotalSeconds Mod TIMEMAXFORGRAPH, (5000 / (5 * (PressureChamberTemperatureAverage / 10) / 1024)) - 1000)
                                VacuumChamberTemperatureGraph.Rows.Add(DeltaTime.TotalSeconds Mod TIMEMAXFORGRAPH, (5000 / (5 * (VacuumChamberTemperatureAverage / 10) / 1024)) - 1000)
                                PressureChamberPressureGraph.Rows.Add(DeltaTime.TotalSeconds Mod TIMEMAXFORGRAPH, ((5 * (PressureChamberPressureAverage / 10) / 1024) - 0.5) * 3.75 * 6.89475729326)
                                VacuumChamberPressureGraph.Rows.Add(DeltaTime.TotalSeconds Mod TIMEMAXFORGRAPH, ((5 * (VacuumChamberPressureAverage / 10) / 1024) - 0.5) * 3.75 * 6.89475729326)
                                ResWire1Graph.Rows.Add(DeltaTime.TotalSeconds Mod TIMEMAXFORGRAPH, 5 * ((ResWire1Average / 10) / 1024))
                                ResWire2Graph.Rows.Add(DeltaTime.TotalSeconds Mod TIMEMAXFORGRAPH, 5 * ((ResWire2Average / 10) / 1024))
                                UpdateSeries()
                                ZeroAverages()
                            End If
                            ChartResetTime = Now - LastReset
                            If ChartResetTime.TotalSeconds > GRAPHUPDATETIME Then
                                TIMEMAXFORGRAPH = TIMEMAXFORGRAPH + GRAPHUPDATETIME
                                UpdateChart(PressureChamberTemperatureChart)
                                UpdateChart(VacuumChamberTemperatureChart)
                                UpdateChart(PressureChamberPressureChart)
                                UpdateChart(VacuumChamberPressureChart)
                                UpdateChart(ResWire1Chart)
                                UpdateChart(ResWire2Chart)
                                UpdateSeries()
                                LastReset = Now
                            End If
                        Else
                            printText("Message length error: MESSAGE_DATA")
                        End If
                    Case 8 'Event
                        Select Case Message(5)
                            Case 1
                                ArmExperimentButton.Text = "De-arm experiment"
                                receivedMessages.Text = receivedMessages.Text & "Experiment ARMED!" & vbNewLine
                            Case 2
                                ArmExperimentButton.Text = "Arm experiment"
                                receivedMessages.Text = receivedMessages.Text & "Experiment DE-ARMED!" & vbNewLine
                            Case 3
                                printText("AVR reseting: " & Now.ToString)
                                ArmExperimentButton.Text = "Arm experiment"
                            Case 5
                                printText("AVR SDClear recieved: " & Now.ToString)
                            Case 4
                                printText("AVR Checksum Error!")
                            Case 64
                                printText(Message(6))
                            Case 128
                                printText("AVR SDClearStages recieved: " & Now.ToString)
                            Case Else
                                printText("Unknown event recieved: " & Message(5))
                        End Select
                    Case 16 'Stagechange
                        If Message.Length = 11 Then
                            Select Case Message(5)
                                Case 0
                                    turnOffStages()
                                    StagePreLiftOff.BackColor = Color.Green
                                Case 1
                                    turnOffStages()
                                    StageAscend.BackColor = Color.Green
                                Case 2
                                    turnOffStages()
                                    StageMelting.BackColor = Color.Green
                                Case 3
                                    turnOffStages()
                                    StageCooling.BackColor = Color.Green
                                Case 4
                                    turnOffStages()
                                    StageShutdown.BackColor = Color.Green
                            End Select
                        End If
                    Case 32 'Battery
                        If Message.Length = 14 Then
                            Battery1Voltage.BackColor = Color.Green
                            Battery1Voltage.Text = vbNewLine + CStr(Message(5) * 256 + Message(6))
                            Battery1Voltage.Text = 5 * Battery1Voltage.Text / 1024
                            Battery2Voltage.BackColor = Color.Green
                            Battery2Voltage.Text = vbNewLine + CStr(Message(7) * 256 + Message(8))
                            Battery2Voltage.Text = 5 * Battery2Voltage.Text / 1024
                        Else
                            printText("Message length error: MESSAGE_BATTERY")
                        End If

                End Select
            Else
                receivedMessages.Text = receivedMessages.Text & "Checksum error occured" & vbNewLine
                Dim j As Integer = 0
                While j <> Message.Length
                    receivedMessages.Text = receivedMessages.Text & " " & CStr(Message(j))
                    j = j + 1
                End While
                receivedMessages.Text = receivedMessages.Text & vbNewLine
            End If

            messageReceived = False
        Else
            printText("Message length error: General")
            messageReceived = False
        End If

    End Sub

    Private Sub printText(ByVal Text As String)
        receivedMessages.Text = receivedMessages.Text & Text & vbNewLine
    End Sub

    Private Sub turnOffStages()
        StagePreLiftOff.BackColor = Color.Red
        StageAscend.BackColor = Color.Red
        StageMelting.BackColor = Color.Red
        StageCooling.BackColor = Color.Red
        StageShutdown.BackColor = Color.Red
    End Sub

    Private Sub putByte(ByVal data As Byte)

        If writeOffset > 512 Then
            writeOffset = 0
            printText("Buffer overflow, clearing buffer.")
        End If

        receiveBuffer(writeOffset) = data
        writeOffset = writeOffset + 1
        If writeOffset >= 3 Then
            If receiveBuffer(writeOffset - 1) = 0 And receiveBuffer(writeOffset - 2) = 255 And receiveBuffer(writeOffset - 3) = 0 Then
                ReDim Message(writeOffset - 1)
                Array.Copy(receiveBuffer, Message, writeOffset - 1)
                Array.Clear(receiveBuffer, 0, receiveBuffer.Length)
                writeOffset = 0
                messageReceived = True
            End If
        End If
    End Sub

    Private Function generateChecksum(ByVal data() As Byte) As Byte()
        Dim tempArray(1) As Byte
        Dim sum1 As Integer = 0
        Dim sum2 As Integer = 0
        Dim index As Integer = 0

        While index < data.Length - 5
            sum1 = (sum1 + data(index)) Mod 255
            sum2 = (sum2 + sum1) Mod 255
            index = index + 1
        End While

        tempArray(0) = sum2
        tempArray(1) = sum1

        Return tempArray
    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ArmExperimentButton.Click
        Dim answer As Integer = MsgBox("Really Arm/Disarm?", MsgBoxStyle.OkCancel)
        Dim sendBuffer(5) As Byte
        Dim checksum(1) As Byte
        If answer = 1 Then
            If ArmExperimentButton.Text = "Arm experiment" Then
                printText("Sending ARM: " & Now.ToString)
                sendBuffer(0) = 1
                checksum = generateChecksum(sendBuffer)
                sendBuffer(1) = checksum(0)
                sendBuffer(2) = checksum(1)
                sendBuffer(3) = 0
                sendBuffer(4) = 255
                sendBuffer(5) = 0
                serialPort.Write(sendBuffer, 0, sendBuffer.Length)
                printText("Sent ARM: " & Now.ToString)
            ElseIf ArmExperimentButton.Text = "De-arm experiment" Then
                printText("Sending DE-ARM: " & Now.ToString)
                sendBuffer(0) = 2
                checksum = generateChecksum(sendBuffer)
                sendBuffer(1) = checksum(0)
                sendBuffer(2) = checksum(1)
                sendBuffer(3) = 0
                sendBuffer(4) = 255
                sendBuffer(5) = 0
                serialPort.Write(sendBuffer, 0, sendBuffer.Length)
                printText("Sent DE-ARM: " & Now.ToString)
            End If
        End If
    End Sub

    Private Sub receivedMessages_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles receivedMessages.TextChanged
        receivedMessages.SelectAll()
        receivedMessages.ScrollToCaret()
    End Sub

    Private Sub AVRResetButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AVRResetButton.Click

        If chxResetCharts.Checked = True Then
            Reset()
        End If
        If chxResetStages.Checked = True Then
            printText("Sending SDClearStages: " & Now.ToString)
            Dim sendBuffer(5) As Byte
            Dim checksum(1) As Byte
            sendBuffer(0) = 128
            checksum = generateChecksum(sendBuffer)
            sendBuffer(1) = checksum(0)
            sendBuffer(2) = checksum(1)
            sendBuffer(3) = 0
            sendBuffer(4) = 255
            sendBuffer(5) = 0
            serialPort.Write(sendBuffer, 0, sendBuffer.Length)
            printText("Sent SDClearStages: " & Now.ToString)
        End If
        If chxResetSDCard.Checked = True And chxResetAVR.Checked = False Then
            Dim answer As Integer = MsgBox("Really clear SD-Card?", MsgBoxStyle.OkCancel, "Clear SD Card?")
            If answer = 1 Then
                printText("Sending SDClear: " & Now.ToString)
                Dim sendBuffer(5) As Byte
                Dim checksum(1) As Byte
                sendBuffer(0) = 8
                checksum = generateChecksum(sendBuffer)
                sendBuffer(1) = checksum(0)
                sendBuffer(2) = checksum(1)
                sendBuffer(3) = 0
                sendBuffer(4) = 255
                sendBuffer(5) = 0
                serialPort.Write(sendBuffer, 0, sendBuffer.Length)
                printText("Sent SDClear: " & Now.ToString)
            End If
        End If
        If chxResetAVR.Checked = True And chxResetSDCard.Checked = False Then
            printText("Sending Reset: " & Now.ToString)
            Dim sendBuffer(5) As Byte
            Dim checksum(1) As Byte
            sendBuffer(0) = 32
            checksum = generateChecksum(sendBuffer)
            sendBuffer(1) = checksum(0)
            sendBuffer(2) = checksum(1)
            sendBuffer(3) = 0
            sendBuffer(4) = 255
            sendBuffer(5) = 0
            serialPort.Write(sendBuffer, 0, sendBuffer.Length)
            printText("Sent Reset: " & Now.ToString)
        End If
        If chxResetAVR.Checked = True And chxResetSDCard.Checked = True Then
            printText("Sending Reset SD and AVR: " & Now.ToString)
            Dim sendBuffer(5) As Byte
            Dim checksum(1) As Byte
            sendBuffer(0) = 16
            checksum = generateChecksum(sendBuffer)
            sendBuffer(1) = checksum(0)
            sendBuffer(2) = checksum(1)
            sendBuffer(3) = 0
            sendBuffer(4) = 255
            sendBuffer(5) = 0
            serialPort.Write(sendBuffer, 0, sendBuffer.Length)
            printText("Sent Reset SD and AVR: " & Now.ToString)
        End If
    End Sub

    Private Sub UpdateSeries()
        PressureChamberTemperatureChart.Series(0).Points.DataBind(PressureChamberTemperatureGraph.DefaultView, "TimePoint", "Value", Nothing)
        VacuumChamberTemperatureChart.Series(0).Points.DataBind(VacuumChamberTemperatureGraph.DefaultView, "TimePoint", "Value", Nothing)
        PressureChamberPressureChart.Series(0).Points.DataBind(PressureChamberPressureGraph.DefaultView, "TimePoint", "Value", Nothing)
        VacuumChamberPressureChart.Series(0).Points.DataBind(VacuumChamberPressureGraph.DefaultView, "TimePoint", "Value", Nothing)
        ResWire1Chart.Series(0).Points.DataBind(ResWire1Graph.DefaultView, "TimePoint", "Value", Nothing)
        ResWire2Chart.Series(0).Points.DataBind(ResWire2Graph.DefaultView, "TimePoint", "Value", Nothing)
    End Sub
    Private Sub UpdateChart(ByVal Chart As System.Windows.Forms.DataVisualization.Charting.Chart)
        With Chart.ChartAreas(0)
            .AxisX.Minimum = 0
            .AxisX.Maximum = TIMEMAXFORGRAPH
            .AxisY.Minimum = 0
            .AxisY.Maximum = 7
            .AxisY.Interval = 4
            .AxisX.Title = "Time"
            .AxisY.Title = "Value"
        End With
    End Sub

    Private Sub UpdateChart2(ByVal Chart As System.Windows.Forms.DataVisualization.Charting.Chart)
        With Chart.ChartAreas(0)
            .AxisX.Minimum = 0
            .AxisX.Maximum = TIMEMAXFORGRAPH
            .AxisY.Minimum = 0
            .AxisY.Maximum = 1000
            .AxisY.Interval = 500
            .AxisX.Title = "Time"
            .AxisY.Title = "Value"
        End With
    End Sub
    Private Sub UpdateChart3(ByVal Chart As System.Windows.Forms.DataVisualization.Charting.Chart)
        With Chart.ChartAreas(0)
            .AxisX.Minimum = 0
            .AxisX.Maximum = TIMEMAXFORGRAPH
            .AxisY.Minimum = 0
            .AxisY.Maximum = 120
            .AxisY.Interval = 30
            .AxisX.Title = "Time"
            .AxisY.Title = "Value"
        End With
    End Sub

    Private Sub Reset()
        TimeStart = Now
        TimeNow = Now
        FirstData = False
        TIMEMAXFORGRAPH = GRAPHUPDATETIME


        UpdateChart2(PressureChamberTemperatureChart)
        UpdateChart2(VacuumChamberTemperatureChart)
        UpdateChart3(PressureChamberPressureChart)
        UpdateChart3(VacuumChamberPressureChart)
        UpdateChart(ResWire1Chart)
        UpdateChart(ResWire2Chart)
        UpdateSeries()

        PressureChamberTemperatureAverage = 0
        VacuumChamberTemperatureAverage = 0
        PressureChamberPressureAverage = 0
        VacuumChamberPressureAverage = 0
        ResWire1Average = 0
        ResWire2Average = 0
        DataSampleCount = 0

        PressureChamberTemperatureGraph.Clear()
        VacuumChamberTemperatureGraph.Clear()
        PressureChamberPressureGraph.Clear()
        VacuumChamberPressureGraph.Clear()
        ResWire1Graph.Clear()
        ResWire2Graph.Clear()

        LastReset = Now

        turnOffStages()
        ExperimentOKTextBox.BackColor = Color.Red
        PressureChamberTemperatureTextbox.BackColor = Color.Red
        VacuumChamberTemperatureTextBox.BackColor = Color.Red
        PressureChamberPressureTextBox.BackColor = Color.Red
        VacuumChamberPressureTextBox.BackColor = Color.Red
        ResWire1TemperatureTextBox.BackColor = Color.Red
        ResWire2TemperatureTextBox.BackColor = Color.Red
        Battery1Voltage.BackColor = Color.Red
        Battery2Voltage.BackColor = Color.Red
    End Sub
    Private Sub SetupGraphs()
        Try
            PressureChamberTemperatureGraph.Columns.Add("TimePoint", GetType(Integer))
            PressureChamberTemperatureGraph.Columns.Add("Value", GetType(Integer))

            VacuumChamberTemperatureGraph.Columns.Add("TimePoint", GetType(Integer))
            VacuumChamberTemperatureGraph.Columns.Add("Value", GetType(Integer))

            PressureChamberPressureGraph.Columns.Add("TimePoint", GetType(Integer))
            PressureChamberPressureGraph.Columns.Add("Value", GetType(Integer))

            VacuumChamberPressureGraph.Columns.Add("TimePoint", GetType(Integer))
            VacuumChamberPressureGraph.Columns.Add("Value", GetType(Integer))

            ResWire1Graph.Columns.Add("TimePoint", GetType(Integer))
            ResWire1Graph.Columns.Add("Value", GetType(Integer))

            ResWire2Graph.Columns.Add("TimePoint", GetType(Integer))
            ResWire2Graph.Columns.Add("Value", GetType(Integer))

            UpdateChart2(PressureChamberTemperatureChart)
            UpdateChart2(VacuumChamberTemperatureChart)
            UpdateChart3(PressureChamberPressureChart)
            UpdateChart3(VacuumChamberPressureChart)
            UpdateChart(ResWire1Chart)
            UpdateChart(ResWire2Chart)


            With PressureChamberPressureChart.Series(0)
                .Points.DataBind(PressureChamberPressureGraph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With

            With PressureChamberTemperatureChart.Series(0)
                .Points.DataBind(PressureChamberTemperatureGraph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With
            With VacuumChamberTemperatureChart.Series(0)
                .Points.DataBind(VacuumChamberTemperatureGraph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With
            With PressureChamberPressureChart.Series(0)
                .Points.DataBind(PressureChamberPressureGraph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With
            With VacuumChamberPressureChart.Series(0)
                .Points.DataBind(VacuumChamberPressureGraph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With
            With ResWire1Chart.Series(0)
                .Points.DataBind(ResWire1Graph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With
            With ResWire2Chart.Series(0)
                .Points.DataBind(ResWire2Graph.DefaultView, "TimePoint", "Value", Nothing)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
            End With

        Catch ex As Exception
            MsgBox("Failed to setup graphs: " + ex.Message)
        End Try
    End Sub
    Private Sub ZeroAverages()
        PressureChamberTemperatureAverage = 0
        VacuumChamberTemperatureAverage = 0
        PressureChamberPressureAverage = 0
        VacuumChamberPressureAverage = 0
        ResWire1Average = 0
        ResWire2Average = 0
        DataSampleCount = 0
    End Sub
    Private Sub ReadDataMessage()
        PressureChamberTemperatureTextbox.BackColor = Color.Green
        PressureChamberTemperatureAverage = PressureChamberTemperatureAverage + Message(5) * 256 + Message(6)
        PressureChamberTemperatureTextbox.Text = Format(((5000 / (5 * (Message(5) * 256 + Message(6)) / 1024)) - 1000), "F")

        VacuumChamberTemperatureTextBox.BackColor = Color.Green
        VacuumChamberTemperatureAverage = VacuumChamberTemperatureAverage + Message(7) * 256 + Message(8)
        VacuumChamberTemperatureTextBox.Text = Format((5000 / (5 * (Message(7) * 256 + Message(8)) / 1024)) - 1000, "F")

        PressureChamberPressureTextBox.BackColor = Color.Green
        PressureChamberPressureAverage = PressureChamberPressureAverage + Message(9) * 256 + Message(10)
        PressureChamberPressureTextBox.Text = Format(((5 * (Message(9) * 256 + Message(10)) / 1024) - 0.5) * 3.75 * 6.89475729326, "F")

        VacuumChamberPressureTextBox.BackColor = Color.Green
        VacuumChamberPressureAverage = VacuumChamberPressureAverage + Message(11) * 256 + Message(12)
        VacuumChamberPressureTextBox.Text = Format(((5 * (Message(11) * 256 + Message(12)) / 1024) - 0.5) * 3.75 * 6.89475729326, "F")

        ResWire1TemperatureTextBox.BackColor = Color.Green
        ResWire1TemperatureTextBox.Text = Format(5 * ((Message(13) * 256 + Message(14)) / 1024), "F")
        ResWire1Average = ResWire1Average + Message(13) * 256 + Message(14)

        ResWire2TemperatureTextBox.BackColor = Color.Green
        ResWire2TemperatureTextBox.Text = Format(5 * ((Message(15) * 256 + Message(15)) / 1024), "F")
        ResWire2Average = ResWire2Average + Message(15) * 256 + Message(16)
    End Sub
End Class
